import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class SeqList<E>{
    Object[] elementData = new Object[]{};//存放元素的空间`
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//默认空间
    private static final int DEFAULT_CAPACITY = 10;//默认容量大小
    private int size =0;
    private int modCount=0;

    public boolean add(E e) {     //尾插e
        ensureCapacityInternal(size + 1);
        elementData[size++]=e;
        return true;//返回值由collection.add指定
    }

    private void ensureCapacityInternal(int minCapacity) {
        ensureCapacity(calculateCapacity(elementData, minCapacity));
    }     //调用ensureCapacity和calculateCapacity方法

    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        // 两个参数 1.elementData :ArrayList存放数据的数组  2.minCapacity:（新的数组）所需的最小容量
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            //1.如果ArrayList存放数据的数组 = 未指定容量的初始化数组
            return Math.max(DEFAULT_CAPACITY, minCapacity); //返回两个中最大的那个
        }
        return minCapacity;  //2.如果Arraylist已经指定容量，则返回minCapacity
    }

    private void ensureCapacity(int minCapacity) {
        modCount++; //modCount记录Arraylist修改次数的量
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    private void grow(int minCapacity) {
        //获取旧空间大小
        int oldCapacity = elementData.length;

        //预计按照1.5倍方式扩容
        int newCapacity = oldCapacity + (oldCapacity >> 1);

        //如果用户需要扩容大小超过原空间1.5倍，按照用户所需大小扩容
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;

        //如果需要扩容的大小超过MAX_ARRAY_SIZE,重新计算容量大小
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);

        //调用copyOf扩容
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    private static int hugeCapacity(int minCapacity) {
        //如果minCapacity小于0，抛出OutOfMemoryError异常
        if (minCapacity < 0)
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
    }

}

//总结：add() ->ensureCapacityInternal()方法(判断是否是无参构造初始化的ArrayList)
// ->ensure ExplicitCapacity()方法(所需容量是否大于当前容量)
// ->grow()(扩容操作) ->arraycopy()(将新复制的数组返回)